<?php
// +----------------------------------------------------------------------
// | LwwanPHP
// +----------------------------------------------------------------------
// | 版权所有 似水星辰 [ 2630481389@qq.com ]
// +----------------------------------------------------------------------
// | 星辰工作室 http://www.sitejs.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------

namespace app\goods\model;

use think\Model as ThinkModel;
use think\Db;

/**
 * 单页模型
 * @package app\user\model
 */
class Goods extends ThinkModel
{
    // 设置当前模型对应的完整数据表名称
    protected $table = '__GOODS__';

    // 自动写入时间戳
    protected $autoWriteTimestamp = true;

    /**
     * 获取商品详情
     * @param $id
     * @param $map
     * @return void
     * @author 刘明美 [ liumingmei@zhongbenjituan.com ]
     */
    public static function get_goods_info($id, $map = [])
    {
        $data = self::view('goods g', true);
        $data = $data->view('goods_body gb', true, 'g.id=gb.goods_id', 'left')
            ->view('upload u', 'path', 'g.thumb=u.id', 'left')
            ->where('g.id', $id)->where($map)->find();
        return $data;
    }

    /**
     * 新增或编辑商品
     * @param $data
     * @return bool
     * @throws \think\exception\PDOException
     * @author 刘明美 [ liumingmei@zhongbenjituan.com ]
     */
    public function save_update($data)
    {
        $spec_data = $data['item'];
        $item_img = $data['item_img'];
        $attr = $data['attr'];
        unset($data['item'], $data['item_img'], $data['attr']);

        $stock_li = [];
        if ($data['is_spec']) {
            foreach ($spec_data as $y) {
                if ($y['status'] == '0') {
                    $stock_li[] = $y['stock'];
                }
            }
        }
        if (!empty($stock_li)) {
            //总库存
            $stock = array_sum($stock_li);
            $data['stock'] = $stock;
        }
        if ($data['is_spec']) {
            if (!$spec_data) {
                $this->error = lang('未设置规格数据');
                return false;
            }         
        }

        self::startTrans();
        try {
            $save_goods_label = $data['goods_label'];

            //保存主表信息
            if (isset($data['id']) && $data['id'] > 0) {      

                $res = self::update($data);
                $res1 = Db::name('goods_body')->where('goods_id', $data['id'])->update(['description' => $data['description'], 'body' => $data['body'], 'mbody' => $data['mbody'], 'update_time' => time()]);
                if (!$res || !$res1) {
                    exception(lang('保存商品失败'));
                }
                //编辑商品标签
                if ($save_goods_label) {
                    if (strpos($save_goods_label, ',')) {
                        $goods_label = array_unique(explode(',', $save_goods_label));
                    } else {
                        $goods_label[] = $save_goods_label;
                    }
                    $old_goods_label = Db::name("goods_label")->where("goods_id", $data['id'])->column("name");
                    //比较数组差异--删除操作
                    $del_goods_label = array_diff($old_goods_label, $goods_label);
                    //比较数组差异--添加操作
                    $add_goods_label = array_diff($goods_label, $old_goods_label);
                    if (count($del_goods_label) > 0) {
                        $del_where[] = ["goods_id", "=", $data['id']];
                        $del_where[] = ["name", "in", $del_goods_label];
                        Db::name("goods_label")->where($del_where)->delete();
                    }
                    if (count($add_goods_label) > 0) {
                        $save_data = [];
                        foreach ($add_goods_label as $key => $value) {
                            $save_data[] = [
                                "goods_id" => $data['id'],
                                "name" => $value
                            ];
                        }
                        Db::name("goods_label")->insertAll($save_data);
                    }
                }
            } else {
               
                $res = self::create($data);
                if (!$res) {
                    exception(lang('新增商品失败'));
                }
                $data['id'] = $res->getLastInsID();
       
                //添加商品标签
                if ($save_goods_label) {
                    if (strpos($save_goods_label, ',')) {
                        $goods_label = array_unique(explode(',', $save_goods_label));
                        $save_data = [];
                        foreach ($goods_label as $key => $value) {
                            $save_data[] = [
                                "goods_id" => $data['id'],
                                "name" => $value
                            ];
                        }
                        Db::name("goods_label")->insertAll($save_data);
                    } else {
                        Db::name("goods_label")->insert(["goods_id" => $data['id'], "name" => $save_goods_label]);
                    }
                }
                $res1 = Db::name('goods_body')->insert(['goods_id' => $data['id'], 'description' => $data['description'], 'body' => $data['body'], 'mbody' => $data['mbody'], 'update_time' => time()]);
                if (!$res1) {
                    exception(lang('新增商品详情失败'));
                }
            }

            //如果没有规格和属性，就提交返回了
            if ($data['is_spec'] == 0) {
                // 提交事务
                self::commit();
                return ['goods_id' => $data['id'], 'info' => 1];
            }      
            $sn = 1;
            //保存SKU
            $okIds = [];
            foreach ($spec_data as $key => $sd) {
                $sd['update_time'] = time();
                if (isset($sd['sku_id']) && $sd['sku_id'] > 0) {                  
                    $res = GoodsSku::where(['sku_id' => $sd['sku_id'], 'key' => $key])->update($sd);    
                    $okIds[] = $sd['sku_id'];
                } else {
                    $sd['goods_id'] = $data['id'];
                    $sd['key'] = $key;
                    if (empty($sd['sku_sn'])) {
                        $sd['sku_sn'] = $data['sn'] . '-' . $sn;
                        $sn++;
                    } else {
                        $getId = GoodsSku::where(['sku_sn' => $sd['sku_sn']])->value("sku_id");
                        if ($getId) {
                            exception(lang('规格货号已存在'));
                        }
                    }           
                    $res = GoodsSku::create($sd);
                    if (!$res) {
                        exception('新增商品SKU失败');
                    }
                    $okIds[] = $res['sku_id'];
                }
            }
            //设置历史无效SKU状态都为失效或者删除
            //GoodsSku::where(['goods_id' => $data['id']])->where("sku_id","not in",$okIds)->update(['status' => 0 , "stock"=>0]);
            GoodsSku::where(['goods_id' => $data['id']])->where("sku_id","not in",$okIds)->delete();

            if ($item_img) {
                //保存规格图片
                foreach ($item_img as $k => $items) {
                    if (isset($items['id'])) {
                        if (GoodsTypeSpecImg::where(['goods_id' => $data['id'], 'spec_image_id' => $k])->count()) {
                            $res = GoodsTypeSpecImg::where(['goods_id' => $data['id'], 'spec_image_id' => $k])->update(['update_time' => time(), 'thumb' => $items['thumb']]);
                        } else {
                            $res = GoodsTypeSpecImg::insert(['goods_id' => $data['id'], 'spec_image_id' => $k, 'update_time' => time(), 'thumb' => $items['thumb']]);
                        }

                        if (!$res) {
                            exception(lang('保存规格图片失败'));
                        }
                    } else {
                        $img[$k]['goods_id'] = $data['id'];
                        $img[$k]['spec_image_id'] = $k;
                        $img[$k]['thumb'] = $items;
                    }
                }

                if ($img) {
                    $res = GoodsTypeSpecImg::insertAll($img);
                    if (!$res) {
                        exception(lang('规格图片插入失败'));
                    }
                }
            }

            //保存或新增属性
            foreach ($attr as $t => $a) {
                if (GoodsTypeAttr::where(['attr_id' => $t, 'goods_id' => $data['id']])->count()) {
                    GoodsTypeAttr::where(['attr_id' => $t, 'goods_id' => $data['id']])->update(['value' => $a]);
                } else {
                    GoodsTypeAttr::insert(['attr_id' => $t, 'goods_id' => $data['id'], 'value' => $a]);
                }
            }

            // 提交事务
            self::commit();
        } catch (\Exception $e) {
            // 回滚事务
            self::rollback();
            $this->error = $e->getMessage();
            return false;
        }
        return ['goods_id' => $data['id'], 'info' => 1];
    }

    /**
     * 获取对应分类的规格
     * @param $cid 分类id
     * @return void
     * @author 刘明美 [ liumingmei@zhongbenjituan.com ]
     */
    public static function getGoodsSpec($cid, $aid = 0)
    {
        if ($cid && $aid == 0) {
            //获取分类对应的类型
            $typeid = Category::where('id', $cid)->value('typeid');
        } else {
            $typeid = $aid;
        }

        //获取类型的规格
        $specList = GoodsTypeSpec::where("typeid", $typeid)->order('sort asc')->column('id,typeid,name,is_upload_image');
        foreach ($specList as $k => $v) {
            $specList[$k]['spec_item'] = GoodsTypeSpecItem::where("specid = " . $v['id'])->order('id')->column('id,specid,item'); // 获取规格项
            foreach ($specList[$k]['spec_item'] as &$spec_item) {
                //默认不选中，前端使用
                $spec_item['active'] = 1;
            }
        }

        return ['typeid' => $typeid, 'specList' => $specList];
    }

    /**
     * 获取商品对应分类的规格以及商品sku
     * @return void
     * @author 刘明美 [ liumingmei@zhongbenjituan.com ]
     */
    public static function getGoodsSpecEdit($goods_id, $spectypeid, $cid)
    {
        if ($cid && !$spectypeid) {
            //获取分类对应的类型
            $typeid = Category::where('id', $cid)->value('typeid');
        } else {
            $typeid = $spectypeid;
        }

        //获取类型的规格
        $specList = GoodsTypeSpec::where("typeid", $typeid)->order('sort asc')->column('id,typeid,name,is_upload_image');

        foreach ($specList as $k => $v) {
            $specList[$k]['spec_item'] = GoodsTypeSpecItem::where("specid = " . $v['id'])->order('id')->column('id,specid,item'); // 获取规格项

            foreach ($specList[$k]['spec_item'] as $s => &$spec_item) {
                if ($v['is_upload_image'] == 1) {
                    $imglist[$s]['path'] = '';
                }

                $specList[$k]['spec_item'][$s]['active'] = 1;
            }
        }

        // SKU列表
        $items = GoodsSku::where('goods_id', $goods_id)->order('key asc')->column("key,sku_id,shop_price,cost_price,market_price,member_price,stock,status,commission,sku_weight,key_name,sku_sn,stock_warning");

        // 获取商品规格图片
        if ($goods_id) {
            $specImageList = Db::name('goods_type_spec_image')->alias('sp')->join('upload u', 'sp.thumb = u.id', 'left')->where("sp.goods_id", $goods_id)->column('sp.spec_image_id,sp.thumb,sp.id,u.path');
            if (!$specImageList) {
                $specImageList = $imglist;
            } else {
                $diffarr = array_diff_key($imglist, $specImageList);
                if ($diffarr) {
                    $specImageList = $specImageList + $diffarr;
                }
            }
        }
        $is_wholesale = Db::name('goods')->where(['id' => $goods_id])->value('is_wholesale');
        if ($is_wholesale == 1) {
            foreach ($items as &$value) {
                $value['wholesale'] = Db::name('goods_wholesale')->where(['goods_id' => $goods_id, 'sku_id' => $value['sku_id']])->field('start_batch,trade_price')->select();
            }
        }
        $data['specs'] = $specList;
        $data['spec_image_list'] = $specImageList;
        $data['items'] = $items;

        return $data;
    }

    /**
     * 获取对应分类的属性
     * @param $cid 分类id
     * @return void
     * @author 刘明美 [ liumingmei@zhongbenjituan.com ]
     */
    public static function getGoodsAttr($cid, $aid)
    {
        //获取分类对应的类型
        if ($cid && !$aid) {
            //获取分类对应的类型
            $typeid = Category::where('id', $cid)->value('typeid');
        } else {
            $typeid = $aid;
        }

        //获取类型的规格
        $attrList = GoodsTypeAttribute::where(["typeid" => $typeid, 'is_show' => 1])->order('sort asc')->column('id,name,typeid,value');
        foreach ($attrList as $k => &$v) {
            $v['value'] = explode(',', $v['value']); // 获取规格项
        }

        return $attrList;
    }

    /**
     * 获取对应分类的属性
     * @param $cid 分类id
     * @return void
     * @author 刘明美 [ liumingmei@zhongbenjituan.com ]
     */
    public static function getGoodsAttrEdit($goods_id, $cid)
    {
        //获取类型的规格
        $attrList = GoodsTypeAttribute::where(["typeid" => $cid, 'is_show' => 1])->order('sort asc')->column('id,name,typeid,value');
        foreach ($attrList as $k => &$v) {
            $v['change'] = GoodsTypeAttr::where(['attr_id' => $v['id'], 'goods_id' => $goods_id])->value('value');
            $v['value'] = explode(',', $v['value']); // 获取规格项
        }

        return $attrList;
    }

    /**
     * 获得商品列表
     * @param array $where 条件
     * @param int $userId 用户id值
     * @param int $page 当前页
     * @return \think\db\Query
     * @author 风轻云淡
     * @editor 似水星辰 [ 2630481389@qq.com ]
     */
    public static function goods_list($where = [], $order = ['id' => 'desc'], $pagesize = '16', $page = 1)
    {
        $lists = Goods::alias("g")->where($where)
            ->where([['g.is_delete', '=', 0], ['g.is_sale', '=', 1], ['g.status', '=', 1]])
            ->field("g.stock,g.id,g.keywords,g.name,g.thumb,g.sales_sum,g.shop_price,g.member_price,g.market_price,
            g.is_shipping,g.is_spec,g.is_hot,g.is_new,g.empirical,g.goods_label_service,g.goods_label_activity,g.discounts,g.share_award_money,g.is_wholesale")
            ->order($order)
            ->page($page,$pagesize)
            ->select();
        foreach ($lists as $k => $v) {
            $lists[$k]['thumb'] = get_file_url($v['thumb']);
            if ($v['is_spec']) {    
                $sku = GoodsSku::field("min(sku_id) as sku_id, sum(stock) as stock")->where(['goods_id' => $v['id']])->find();
                $lists[$k]['stock'] = $sku["stock"];
                $lists[$k]['sku_id'] = $sku['sku_id'];
            }         
            $lists[$k]['goods_label_service'] = GoodsLabelService::getColumn($v['goods_label_service']);
            $lists[$k]['goods_label_activity'] = GoodsLabelService::getColumn($v['goods_label_activity']);            
            $lists[$k]['goods_label'] = GoodsLabel::getGoodsLabels($v["id"]);
        }
        return $lists;
    }
   

    /**
     * 商品详情
     * @param $where
     * @return array|false|null|\PDOStatement|string|ThinkModel
     * @author 风轻云淡
     * @editor 似水星辰 [ 2630481389@qq.com ]
     */
    public function goods_detail($where, $activity_id = 0)
    {
        $goodsInfo = Goods::alias("g")->join("__GOODS_BODY__ gb", "gb.goods_id=g.id")
            /*->join("__UPLOAD__ u", "u.id=g.thumb")*/
            ->where($where)
            ->field("g.id,g.cid,g.adslogan,g.name,g.sales_sum,g.spectypeid,g.click,g.is_recommend,
            g.is_new,g.is_hot,g.shop_price,g.member_price,g.market_price,g.images,g.thumb,gb.body,
            gb.description,g.stock,g.is_spec,g.support_self_mention,g.is_shipping,g.freight_price,g.discounts,g.share_award_money,
            g.goods_label_service,g.goods_label_activity,g.freight_template_id,video,video_img,is_wholesale")
            ->find();
        if ($goodsInfo) {
            $goodsInfo['thumb'] = get_file_url($goodsInfo['thumb']);     
            $goodsInfo['images'] =  $goodsInfo['images'] ? get_files_url($goodsInfo['images']) : [];    
            $goodsInfo['video'] = $goodsInfo['video'] ? get_file_url($goodsInfo['video']) : "";
            $goodsInfo['video_img'] =  $goodsInfo['video_img'] ? get_file_url($goodsInfo['video_img']) : "";
          
            $goodsInfo['goods_label_service'] = GoodsLabelService::getColumn($goodsInfo['goods_label_service']);
            $goodsInfo['goods_label_activity'] =[];            
            $goodsInfo['goods_label'] = GoodsLabel::getGoodsLabels($goodsInfo["id"]);
       
            //查看商品规格
 
            if ($goodsInfo['is_spec'] == 1) {
                //查询商品对应规格
                $map[] = ['goods_id', '=', $goodsInfo['id']];
                $map[] = ['status', '=', 1];
                //获取原价商品规格
                $goodsSpec = GoodsSku::where($map)->field("sku_id, key, key_name, member_price, shop_price,market_price,member_price,stock")->select();
                $goodsSpecIds = $goodsSpec->column('key');//注，这里复用上面的selct查询类获取
                $goodsInfo['stock'] = array_sum($goodsSpec->column('stock'));//注，这里复用上面的selct查询类获取
                
                $sku_spec = self::sku_spec($goodsInfo, $goodsSpec, $goodsSpecIds);

                if (isset($sku_spec['spec_list'])) {
                    $sku_spec['spec_list'] = $sku_spec['spec_list']->toArray();
                    foreach ($sku_spec['spec_list'] as $k => $v) {
                        if (empty($v['spec_value'])) {
                            unset($sku_spec['spec_list'][$k]);
                        }
                    }
                }
                $goodsInfo['spec_list'] = $sku_spec['spec_list'];
                $goodsInfo['sku_list'] = $sku_spec['sku_'];       
                
                $goodsInfo['is_spec'] = empty($goodsInfo['sku_list']) ? 0 : 1;    
         
                //商品属性获得
                // ????为什么不做联合查询？
                $goodsInfo['attr_value'] = GoodsTypeAttribute::view('goods_type_attribute',"id,name")
                        ->view('goods_type_attr',"value as attr_value","goods_type_attr.attr_id = goods_type_attribute.id and goods_type_attr.goods_id = " . $goodsInfo['id'],"left")
                        ->where(['goods_type_attribute.typeid' => $goodsInfo['spectypeid'], 'goods_type_attribute.is_show' => 1])
                        ->order("goods_type_attribute.sort asc")                
                        ->select();

            } else {             
                $goodsInfo['attr_value'] = [];
                $goodsInfo['spec_list'] = [];
            }
        }
        return $goodsInfo ? $goodsInfo : [];
    }

    public static function sku_spec($goodsInfo, $goodsSpec, $goodsSpecIds)
    {
        $specValue = [];
        if ($goodsSpec) {
            $specValueStr = implode("_", $goodsSpecIds);
            $specValue = array_unique(explode("_", trim($specValueStr, "_")));
            $goodsSpecValue = [];
            foreach ($goodsSpec as $key => $value) {
                $goodsSpecValue[$value['key']] = $value;
            }
        }      
        $condition[] = ['typeid', '=', $goodsInfo['spectypeid']];
        $sku_spec['spec_list'] = GoodsTypeSpec::get_spec($condition, $specValue, $goodsInfo['id']);
        $sku_spec['sku_'] = $goodsSpecValue;
        return $sku_spec;
    }

    /**
     * 商品评论
     * @param $where
     * @param int $userId
     * @return array|false|null|\PDOStatement|string|ThinkModel
     * @author zlf
     */
    public static function goods_comment($goodsId)
    {
        $comment = Db::name('goods_comment')->alias('c')
            ->join('user u', 'c.user_id = u.id')
            ->field('c.id,c.thumb,c.create_time,c.content,c.star,u.head_img,u.user_nickname,c.sku_id')
            ->where(['c.goods_id' => $goodsId, 'c.status' => 1])
            ->order('c.create_time desc')
            ->paginate()->each(function ($item) {
                $item['thumb'] = get_file_url($item['thumb']);
                $item['head_img'] = get_file_url($item['head_img']);
                $item['create_time'] = date('Y-m-d', $item['create_time']);
                if ($item['sku_id']) {
                    $item['key_name'] = Db::name('goods_sku')->where('sku_id', $item['sku_id'])->value('key_name');
                }
                return $item;
            });

        return $comment ? $comment : [];
    }

    /*获取推荐商品
    zlf
    */
    public function goods_index($where, $page)
    {
        $recommend = \think\Db::name('goods')
            ->where($where)
            ->field("id,name,thumb,sales_sum,shop_price")
            ->page($page, 4)
            ->select();
        if ($recommend) {
            foreach ($recommend as $k => $v) {
                $recommend[$k]['thumb'] = get_files_url($v['thumb']);
            };
        } else {
            $recommend = [];
        }
        return $recommend;
    }

    /*获取推荐商品
    zlf
    */
    public function goods_search($where, $page, $limit)
    {
        $recommend = Db::name('goods')
            ->where($where)
            ->field("id,cid,name,thumb,sales_sum,shop_price")
            ->page($page, $limit)
            ->select();
        /*           var_dump(Db::name('goods')->getLastSql());*/
        if ($recommend) {
            foreach ($recommend as $k => $v) {
                $recommend[$k]['thumb'] = get_files_url($v['thumb']);
            };
        }

        return $recommend ? $recommend : [];
    }

    /**
     * 查询商品数据
     * @param $where str 查询条件
     * @author 曾虎 [ 1427305236@qq.com ]
     * @since 2020年12月21日16:46:51
     */
    public static function getGoodsList($where = '')
    {
        return self::field("
            GROUP_CONCAT(cid) cids, 
            GROUP_CONCAT(brand_id) brand_ids, 
            GROUP_CONCAT(goods_label_service) goods_label_services
        ")->where($where)
            ->find();
    }

    /**
     * 查询商品数据条数
     * @param $where str 查询条件
     * @author 曾虎 [ 1427305236@qq.com ]
     * @since 2020年12月21日16:51:06
     */
    public static function getGoodsListCount($where = '')
    {
        return self::alias('g')->where($where)->count();
    }


    /**
     * 比较两个二维数组，新数组的值在老数组是否存在且相等
     * 用于判断是否修改了规格数据，数组内元素顺序是打乱的
     */
    public function checkDiff($olddata, $newdata)
    {
        $diff = false;
        foreach ($newdata as $k => $v) {
            if (!isset($olddata[$k])) {
                $diff = true;
            }
            foreach ($v as $vk => $vv) {
                if (!isset($olddata[$k][$vk])) {
                    $diff = true;
                }
                if ($vv != $olddata[$k][$vk]) {
                    $diff = true;
                }
            }
        }
        return $diff;
    }
    /**
     * 获得关键字查询条件，可在数组模式中使用
     * @demo $map[] = Goods::getKeywordWhereMap("123123","g.name|g.keywords");
     * @param string $keyword
     * @param string $field
     * @author 晓风<215628355@qq.com>
     */
    public static function getKeywordWhereMap(string $keyword,string $field = "name"){
        //使用preg_split 分割为数组并用array_filter 去掉空值
        $arr = array_filter( preg_split("/[\s,]+/", $keyword) );   
         //将原有参数添加到数组头部（优先度高）
        array_unshift($arr,$keyword);          
        //使用array_unique去重后
        $arr = array_unique($arr);
        //即可用LIKE查询多个词了：WHERE (`name` LIKE '%a%' OR `name` LIKE '%b%')
        $where = function($query)use($arr,$field){    
            foreach($arr as $q){
               $map[] = [$field,"like",'%'.$q.'%'];
            }
            $query->whereOr($map);
        }; 
        return $where;
    }
    
    
     /**
     * 获得多个字段的FIND_IN_SET条件
     * @demo $map[] = Goods::getFinInsetAll("1,2,3,4,5","ids");
     * @param string $str
     * @param string $field
     * @author 晓风<215628355@qq.com>    
      */
     public static function getFinInsetAll(string $str, $field = 'ids')
    {
        $arr = explode(',', $str);
        $serviceLabel = array_filter(array_unique($arr));
        if(empty($serviceLabel)){
            return false;
        }
        foreach ($serviceLabel as $val) {
            $whereOr[]= ['',"exp", \think\Db::raw("FIND_IN_SET({$val},{$field})")];
        }
        $where =  function($query)use($whereOr){
            $query->whereOr($whereOr);
        };
        return $where;
    }
    
    
    /**
     * 处理body富文本，去掉其他标签，将p标签改成div并设置浮动，清除空白行
     * @param string $body
     * @author 晓风<215628355@qq.com>
     * @return string
     */
    public static function stripTags($body){
        $body = strip_tags($body,"<p><img><b>");
        $body = preg_replace('/<img(.*?)src="(.*?)"(.*?)>/','<img src="\\2" style="display:block;width:100%">',$body);
       // $body = preg_replace("/<\/p>/",'</div>',$body);
        return $body;
    }
}
